<?php
/**
 * Function:
 * Description:
 * Abo 2019/4/27 10:00
 * Email: abo2013@foxmail.com
 */

namespace Abo\Smartsync\Repositories;

use Illuminate\Support\Facades\DB;

class SyncRepository
{
    public $tableName, $updateBatch, $startTime, $endTime;

    public function __construct( string $tableName = '' )
    {
        if ( !$tableName ) {
            throw new \Exception( '未设置表名', false );
        }

        $this->tableName = $tableName;
    }

    /** 获取 新增同步数据 */
    public function getInsertSyncList()
    {
        if ( !$this->updateBatch ) {
            return [];
        }

        $SearchModel = \DB::table( $this->tableName )
            ->where( 'remove_time', '=', 0 )
            ->where( 'update_batch', '=', $this->updateBatch )
            ->where( 'md5_origin', '=', '' )
            ->where( 'md5_new', '!=', '' );

        if ( $this->startTime && $this->endTime ) {
            $SearchModel = $SearchModel
                ->where( 'updated_at', '>=', $this->startTime )
                ->where( 'updated_at', '<', $this->endTime );
        }

        $newSyncList = $SearchModel->get();
        if ( !$newSyncList ) {
            return [];
        }

        return $newSyncList->toArray();
    }

    /** 获取 变更同步数据 */
    public function getUpdateSyncList()
    {
        if ( !$this->updateBatch ) {
            return [];
        }

        $SearchModel = \DB::table( $this->tableName )
            ->where( 'remove_time', '=', 0 )
            ->where( 'update_batch', '=', $this->updateBatch )
            ->where( 'md5_origin', '!=', '' )
            ->where( 'md5_new', '!=', \DB::raw( 'md5_origin' ) ); // 还可以补充其他 业务逻辑条件,搜索出特定逻辑数据

        if ( $this->startTime && $this->endTime ) {
            $SearchModel = $SearchModel
                ->where( 'updated_at', '>=', $this->startTime )
                ->where( 'updated_at', '<', $this->endTime );
        }

        $changeSyncList = $SearchModel->get();
        if ( !$changeSyncList ) { return []; }

        return $changeSyncList->toArray();
    }

    /** 获取 失联同步数据 */
    public function getUnsetSyncList()
    {
        if ( !$this->updateBatch ) {
            return [];
        }

        $SearchModel = \DB::table( $this->tableName )
            ->where( 'update_batch', '!=', $this->updateBatch )
            ->where( 'md5_origin', '!=', DB::raw( 'md5_new' ) )
            ->where( 'md5_new', '=', '' );

        if ( $this->startTime && $this->endTime ) {
            $SearchModel = $SearchModel
                ->where( 'updated_at', '>=', $this->startTime )
                ->where( 'updated_at', '<', $this->endTime );
        }

        $unsetSyncList = $SearchModel->get();
        if ( !$unsetSyncList ) { return []; }

        return $unsetSyncList->toArray();
    }

    /** 单个插入更新 @throws \Exception */
    public function duplicateKeyInsert( array $fileCategoryRelationArr, string $tableName = '' )
    {
        if ( !$fileCategoryRelationArr || !$tableName ) { return false; }

        $insertColumns = null;
        $updateColumnsKeyArr = $updateColumnsKeyStr = false;

        // 添加部分绑定
        $insertColumns = array_keys( $fileCategoryRelationArr );
        $insertColumnsBindValue = array_values( $fileCategoryRelationArr );

        $insertColumnsQuestionStr = implode( ',', array_fill( 0, count( $fileCategoryRelationArr ), '?' ) );
        $insertColumnsKeyStr = implode( ',', $insertColumns );

        // 更新部分数据绑定
        foreach ( $fileCategoryRelationArr as $k2cate => $v2cate ) {
            $updateColumnsKeyArr[] = "{$k2cate}='".addslashes($v2cate)."'";
        }

        $updateColumnsKeyStr = implode( ',', $updateColumnsKeyArr );

        $duplicateInsertSql = "insert into {$tableName} ( {$insertColumnsKeyStr} ) "
            . "values ( {$insertColumnsQuestionStr} )  ON DUPLICATE KEY UPDATE {$updateColumnsKeyStr}";
        $ret2Return = \DB::insert( $duplicateInsertSql, $insertColumnsBindValue );

        return $ret2Return;
    }

    /** 单例 */
    public function updateBatchInstance()
    {
        if ( !$this->updateBatch ) {
            $this->updateBatch = date( 'mdHi' ) . substr( md5( time() ), 0, 3 );
        }

        return $this->updateBatch;
    }

    /**
     * 设置 返回时间段
     * @param array $timePeriod
     * @return bool
     */
    public function setSyncTimePeriod( array $timePeriod = [] )
    {
        list( $this->startTime, $this->endTime ) = $timePeriod;

        if ( !$this->startTime ) {
            $this->startTime = date( 'Y-m-d' );
        }

        if ( !$this->endTime ) {
            $this->endTime = date( 'Y-m-d H:i:s' );
        }

        $this->endTime = date( 'Y-m-d H:i:s', ( strtotime( $this->endTime ) + 60 ) );
        return true;
    }
}